package com.kang.commons.util;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;

/**
 * @program: service
 * @description: map类型转obj类型工具
 * @author: K.faWu
 * @create: 2022-02-28 11:06
 **/

public class MapToObjUtil {
    /**
     * Map<String,Object>转Obj对象
     *
     * @param <T>
     *
     * @param map key:对应obj中的字段，value:字段的值
     * @return
     * @throws ClassNotFoundException
     */
    public static <T> T map2Obj(Map<String, Object> map, Class<T> clazz) throws ClassNotFoundException {
        T obj = null;
        Set<Map.Entry<String, Object>> set = map.entrySet();
        Iterator<Map.Entry<String, Object>> iterator = set.iterator();
        String setMethod = "";
        String key = "";
        try {
            try {
                obj = clazz.getDeclaredConstructor(new Class[] {}).newInstance(new Object[] {});
            } catch (NoSuchMethodException e1) {
                System.out.println(obj + "中没有对应的构造方法方法");
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
            while (iterator.hasNext()) {
                Map.Entry<String, Object> entry = iterator.next();
                key = entry.getKey();
                Object value = entry.getValue();
                Field field = null;
                try {
                    field = clazz.getDeclaredField(key);
                } catch (NoSuchFieldException e) {}
                if (field != null && value != null) {
                    setMethod = "set" + key.substring(0, 1).toUpperCase() + key.substring(1);
                    Method method = null;
                    try {
                        method = clazz.getDeclaredMethod(setMethod, new Class[] { field.getType() });
                    } catch (NoSuchMethodException e) {
                        System.out.println(obj + "中没有对应的方法：" + setMethod);
                    }
                    if (method != null) {
                        method.invoke(obj, toObject(value, field));
                    }
                }
            }
        } catch (IllegalArgumentException | SecurityException | InstantiationException | IllegalAccessException | InvocationTargetException e1) {
            e1.printStackTrace();
        }
        return obj;
    }

    public static <T> List<T> listToObject(List<Map<String, Object>> list, Class<?> clazz) throws ClassNotFoundException {
        List<T> resultList = null;
        if (list != null && list.size() > 0) {
            resultList = new ArrayList<T>();
            Iterator<Map<String, Object>> iterator = list.iterator();
            while (iterator.hasNext()) {
                T obj = null;
                try {
                    obj = (T) clazz.newInstance();
                } catch (InstantiationException | IllegalAccessException e) {
                    e.printStackTrace();
                }
                Map<String, Object> map = iterator.next();
                map2Obj(map, clazz);
                resultList.add(obj);
            }
        }
        return resultList;
    }

    /**
     * 类型匹配
     *
     * @param value
     * @param field
     * @return
     */
    private static Object toObject(Object value, Field field) {
        if (field.getType() == String.class) {
            value = value + "";
        } else {
            if ("null".equals(value) || "".equals(value)) {
                value = "0";
            }
            if (field.getType() == int.class || field.getType() == Integer.class) {
                value = Integer.valueOf("" + value);
            } else if (field.getType() == double.class || field.getType() == Double.class) {
                value = Double.valueOf("" + value);
            } else if (field.getType() == float.class || field.getType() == Float.class) {
                value = Float.valueOf("" + value);
            } else if (field.getType() == short.class || field.getType() == Short.class) {
                value = Short.valueOf("" + value);
            } else if (field.getType() == boolean.class || field.getType() == Boolean.class) {
                value = Boolean.valueOf("" + value);
            } else if (field.getType() == byte.class || field.getType() == Byte.class) {
                value = Byte.valueOf("" + value);
            } else if (field.getType() == long.class || field.getType() == Long.class) {
                value = Long.valueOf("" + value);
            } else if (field.getType() == char.class || field.getType() == Character.class) {
                value = (Character) value;
            }
        }
        return value;
    }
}
